package battlecruiser.board.cell.coordinate;

import org.apache.log4j.Logger;
import org.springframework.util.Assert;

/**
 * @author tymoshya
 * @since 15.06.12
 */
public class Coordinate {

    private static final Logger LOG = Logger.getLogger(Coordinate.class);

    public static Coordinate valueOf(String coordinateAsString) {
        return new Coordinate(coordinateAsString);
    }

    private int i, j;

    public Coordinate(int i, int j) {
        this.i = i;
        this.j = j;
    }

    public Coordinate(String coordinateAsString) {
        /*
            e.g. A10 means: i = 9, j = 0; (A->j, number->i)
         */
        Assert.isTrue((coordinateAsString != null) && (coordinateAsString.length() >= 0) && (coordinateAsString.length() <= 3), "Coordinate should look like \"A2\"!");
        this.i = parseI(coordinateAsString);
        this.j = parseJ(coordinateAsString);
        LOG.trace(String.format("String \"%s\" was parsed into coordinate (%s, %s)", coordinateAsString, i, j));
    }

    /**
     * @param that a coordinate to compare with
     * @return true if this coordinate is upper than that one
     */
    public boolean isAboveThan(Coordinate that) {
        return this.getI() < that.getI();
    }

    /**
     * @param that a coordinate to compare with
     * @return true if this is lefter than that one
     */
    public boolean isLefterThan(Coordinate that) {
        return this.getJ() < that.getJ();
    }

    public int getJ() {
        return j;
    }

    public int getI() {
        return i;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Coordinate)) return false;

        Coordinate that = (Coordinate) o;

        return i == that.i && j == that.j;
    }

    @Override
    public int hashCode() {
        int result = j;
        result = 31 * result + i;
        return result;
    }

    @Override
    public String toString() {
        return parseJ(j) + parseI(i);
    }

    private int parseJ(String s) {
        String j = Character.toString(s.charAt(0));
        Verticals vertical = Verticals.valueOf(j);
        return vertical.ordinal();
    }

    private String parseJ(int j) {
        return Verticals.values()[j].toString();
    }

    private int parseI(String s) {
        String i = s.substring(1);
        return new Integer(i) - 1;
    }

    private String parseI(int I) {
        return Integer.toString(I + 1);
    }
}
